%%%-------------------------------------------------------------------
%% @doc chat top level supervisor.
%% @end
%%%-------------------------------------------------------------------
%%%=============================================================================
%%% @private chat supervisor
%%%
%%% Hierarchy:
%%%   chat_sup (one_for_one)
%%%     |
%%%     +--chat_channel_manage
%%%     |
%%%     +--chat_channel_sup
%%%     |    |
%%%     |    +-- chat_channel_worker 1
%%%     |    |
%%%     |    +-- chat_channel_worker 2
%%%     |    |
%%%     |    |...
%%%     |
%%%     +-- chat_private_manage
%%%     |
%%%     +-- chat_private_sup
%%%          |
%%%          +-- chat_private_worker 1
%%%          |
%%%          +-- chat_private_worker 2
%%%          |
%%%          |...
%%%
%%% @end
%%%=============================================================================
-module(chat_sup).

-behaviour(supervisor).

-export([start_link/0]).

-export([init/1]).

-define(SERVER, ?MODULE).

start_link() ->
    supervisor:start_link({local, ?SERVER}, ?MODULE, []).

%% sup_flags() = #{strategy => strategy(),         % optional
%%                 intensity => non_neg_integer(), % optional
%%                 period => pos_integer()}        % optional
%% child_spec() = #{id => child_id(),       % mandatory
%%                  start => mfargs(),      % mandatory
%%                  restart => restart(),   % optional
%%                  shutdown => shutdown(), % optional
%%                  type => worker(),       % optional
%%                  modules => modules()}   % optional
init([]) ->
    Config0     = application:get_all_env(chat),
    PPAmount    = proplists:get_value(chat_private_process_amount, Config0, 10),
    SaveMax     = proplists:get_value(chat_save_message_max,       Config0, 1000),
    FetchAmount = proplists:get_value(chat_fetch_message_amount,   Config0, 10),

    Config = 
        #{ chat_private_process_amount  => PPAmount
         , chat_save_message_max        => SaveMax
         , chat_fetch_message_amount    => FetchAmount
         },

    SupFlags = 
        #{ strategy     => one_for_one
         , intensity    => 10
         , period       => 10
         },

    %% chat_channel_manage
    ChatChannelManage = 
        #{ id       => chat_channel_manage
         , start    => {chat_channel_manage, start_link, [Config]}
         , restart  => transient
         , shutdown => 1000
         , type     => worker
         , modules  => [chat_channel_manage]
         },
    %% chat_channel_sup
    ChatChannelSup = 
        #{ id       => chat_channel_sup
         , start    => {chat_channel_sup, start_link, [Config]}
         , restart  => permanent
         , shutdown => infinity
         , type     => supervisor
         , modules  => [chat_channel_sup]
         },
    %% chat_private_manage
    ChatPrivateManage = 
        #{ id       => chat_private_manage
         , start    => {chat_private_manage, start_link, [Config]}
         , restart  => transient
         , shutdown => 1000
         , type     => worker
         , modules  => [chat_private_manage]
         },
    %% chat_private_sup
    ChatPrivateSup = 
        #{ id       => chat_private_sup
         , start    => {chat_private_sup, start_link, [Config]}
         , restart  => permanent
         , shutdown => infinity
         , type     => supervisor
         , modules  => [chat_private_sup]
         },

    ChildSpecs = 
        [ ChatChannelManage
        , ChatChannelSup
        , ChatPrivateManage
        , ChatPrivateSup
        ],
    {ok, {SupFlags, ChildSpecs}}.

%% internal functions
